package com.cargo.base.utils;

import com.cargo.base.exceptions.CommonException;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class CompareObjectUtil {
	/**
	 * 
	 * <p>
	 * 两个对象比对，如果值不同，则在newObj对应的位置加上<div style='color:red;'></div> </p>
	 * 
	 * @author ZHU CHEN
	 * @version 0.1 2016年8月9日
	 * @param newObj
	 * @param oldObj
	 * @return Object
	 */
	public static Object compareObject(Object newObj, Object oldObj) {
		if (newObj == null) {
			return oldObj;
		}
		if (oldObj == null) {
			return newObj;
		}
		Field[] fields = getAll(newObj, newObj.getClass());
		for (int i = 0; i < fields.length; i++) {
			String filedname = fields[i].getName();
			Method newmethod = null;
			try {
				if (fields[i].getType().getName().startsWith("com.cargo.")) {
					newmethod = newObj.getClass().getMethod(
							"get" + String.valueOf(filedname.charAt(0)).toUpperCase() + filedname.substring(1),
							(Class<?>[]) null);
					Object value1 = newmethod.invoke(newObj, new Object[0]);
					Object value2 = newmethod.invoke(oldObj, new Object[0]);
					compareObject(value1, value2);
				} else if (fields[i].getType().getName().equals("java.lang.String")) {
					newmethod = newObj.getClass().getMethod(
							"get" + String.valueOf(filedname.charAt(0)).toUpperCase() + filedname.substring(1),
							(Class<?>[]) null);
					Object value1 = newmethod.invoke(newObj, new Object[0]);
					Object value2 = newmethod.invoke(oldObj, new Object[0]);

					if (value1 == null && value2 == null) {
						continue;
					} else if (value1 == null && value2 != null) {
						value1 = "<div class=red_font>新值为空(旧值:" + String.valueOf(value2) + ")</div>";
					} else if (value1 != null && value2 == null) {
						value1 = "<div class=red_font>" + value1 + "(旧值为空)</div>";
					} else if (value1 != value2 && (!(value1.equals(value2)))) {
						value1 = "<div class=red_font>" + value1 + "(旧值:" + String.valueOf(value2) + ")</div>";
					}
					try {
						newObj.getClass().getMethod(
								"set" + String.valueOf(filedname.charAt(0)).toUpperCase() + filedname.substring(1),
								String.class).invoke(newObj, new Object[] { value1 });
					} catch (Exception e) {
						throw new CommonException("比对赋值异常：" + filedname);
					}
				}
			} catch (Exception e1) {
				continue;
			}
		}
		return newObj;
	}

	/**
	 * 
	 * <p>
	 * 两个对象比对，如果值不同，则在newObj对应的位置加上<div style='color:red;'></div> </p>
	 * 
	 * @author ZHU CHEN
	 * @version 0.1 2016年8月9日
	 * @param newObj
	 * @param oldObj
	 * @return Object
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List<Object> compareList(List newList, List oldList) {
		if (newList == null || newList.size() == 0) {
			return newList;
		}
		if (oldList == null || oldList.size() == 0) {
			return newList;
		}
		List lists = new ArrayList();//存放对象反过来的新值集合
		for (Object o : newList) {
			try {
				String idval = (String) o.getClass().getMethod("getId", (Class<?>[]) null).invoke(o, new Object[0]);
				boolean flag=true;
				for (Object o2 : oldList) {
					String idval2 = (String) o2.getClass().getMethod("getId", (Class<?>[]) null).invoke(o2,
							new Object[0]);
					if (idval.equals(idval2)) {
						compareObject(o, o2);
						oldList.remove(o2);
						 flag=false;
						break;
					}
				}
				if(flag){
					Object newo = null;
					for (Object oo : oldList) {
						newo = compareObject(oo, o);
					}
					lists.add(newo);
				}
			} catch (Exception e) {
				return lists;
			}
		}
		return lists;
	}

	public static void main(String[] args) {
//		List<BookingChangeVo> v1= new ArrayList<BookingChangeVo>();
//		List<BookingChangeVo> v2= new ArrayList<BookingChangeVo>();
//		BookingChangeVo vo1 = new BookingChangeVo();
//		BookingChangeVo vo2 = new BookingChangeVo();
//		vo1.setId(1);
//		vo2.setId(2);
//		vo1.setVessel("1111");
//		vo2.setVessel("1111_2");
//		vo1.setVessel("2222");
//		vo2.setVessel("2222_2");
//		v1.add(vo1);
//		v2.add(vo2);
//		List list = compareList(v1, v2);
//		System.out.println(list.size());
//		System.out.println(list);
//		long i = System.currentTimeMillis();
//		compareObject(vo1, vo2);
//		long j = System.currentTimeMillis();
//		System.out.println(j - i);
//		System.out.println(vo1.getVessel());
//		System.out.println(vo1.getRemark());
//		System.out.println(vo1.getVo2().getBookingId());
	}

	private static Field[] getAll(Object obj, Class<? extends Object> clazz) {
		Field[] result;
		Field[] fields = clazz.getDeclaredFields();
		if (!"java.lang.Object".equals(clazz.getSuperclass().getName())) {
			Field[] fields2 = getAll(obj, obj.getClass().getSuperclass());
			result = new Field[fields.length + fields2.length];
			int index = 0;
			for (int i = 0; i < fields.length; i++) {
				result[index++] = fields[i];
			}
			for (int j = 0; j < fields2.length; j++) {
				result[index++] = fields2[j];
			}
		} else {
			result = fields;
		}
		return result;
	}
}
